/**
 * 文件上传中间件
 * 使用multer处理文件上传，配置内存存储和验证规则
 */

import multer from 'multer';
import { AppError } from '../utils/appError.js';

// 文件大小限制（10MB）
const MAX_FILE_SIZE = 10 * 1024 * 1024;

// 允许的MIME类型
const ALLOWED_MIME_TYPES = ['image/jpeg', 'image/jpg', 'image/png'];

// 配置multer使用内存存储
const storage = multer.memoryStorage();

/**
 * 文件过滤器：验证文件类型
 * @param {Object} req - Express请求对象
 * @param {Object} file - 上传的文件对象
 * @param {Function} cb - 回调函数
 */
const fileFilter = (req, file, cb) => {
  // 检查MIME类型
  if (ALLOWED_MIME_TYPES.includes(file.mimetype)) {
    // 接受文件
    cb(null, true);
  } else {
    // 拒绝文件
    cb(
      new AppError(
        'INVALID_FILE_TYPE',
        '仅支持JPEG和PNG格式的图片',
        400
      ),
      false
    );
  }
};

/**
 * multer配置
 */
const upload = multer({
  storage: storage,
  limits: {
    fileSize: MAX_FILE_SIZE,
  },
  fileFilter: fileFilter,
});

/**
 * 单文件上传中间件（字段名为'image'）
 */
export const uploadSingle = upload.single('image');

/**
 * 多文件上传中间件（字段名为'images'，最多5个）
 */
export const uploadMultiple = upload.array('images', 5);

/**
 * 错误处理中间件：处理multer错误
 * @param {Error} err - 错误对象
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - Express next函数
 */
export const handleMulterError = (err, req, res, next) => {
  if (err instanceof multer.MulterError) {
    // Multer特定错误
    let message = '文件上传失败';
    let type = 'UPLOAD_ERROR';

    switch (err.code) {
      case 'LIMIT_FILE_SIZE':
        message = `文件大小不能超过${MAX_FILE_SIZE / 1024 / 1024}MB`;
        type = 'FILE_TOO_LARGE';
        break;
      case 'LIMIT_FILE_COUNT':
        message = '文件数量超过限制';
        type = 'TOO_MANY_FILES';
        break;
      case 'LIMIT_UNEXPECTED_FILE':
        message = '意外的文件字段';
        type = 'UNEXPECTED_FIELD';
        break;
      default:
        message = err.message;
    }

    return res.status(400).json({
      success: false,
      error: {
        type: type,
        message: message,
      },
    });
  }

  // 其他错误传递给下一个错误处理中间件
  next(err);
};

export default {
  uploadSingle,
  uploadMultiple,
  handleMulterError,
};

